package com.mall.controller;

import com.mall.db.domain.JobAndTrigger;
import com.mall.db.service.SchedulerService;
import com.mall.job.BaseJob;
import org.quartz.*;
import org.quartz.spi.OperableTrigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 *
 */
/*

@RestController
@RequestMapping("/system/sc")
public class SchedulerController extends BaseController<JobAndTrigger>{

    @Resource(name = "schedulerService")
    private SchedulerService ss;

    @Resource(name = "scheduler")
    private Scheduler scheduler;

    @Override
    public Map<String, Object> find(JobAndTrigger jt) {

        List<JobAndTrigger> list = ss.find();

        return this.findMap(list, list.size());
    }

    @Override
    public Map<String, Object> add(JobAndTrigger jt) {

        Map<String, Object> map = new HashMap<>();
        try {

            //启动调度器
            scheduler.start();
            //构建任务详情
            JobDetail detail = JobBuilder.newJob(getClass(jt.getClassName()).getClass())
                    .withIdentity(jt.getJobName(), jt.getJobGroup())
                    .build();

            //corn表达式构建
            CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule(jt.getCorn());

            //构建新的触发器
            CronTrigger trigger = TriggerBuilder.newTrigger().
                    withIdentity(jt.getTriggerName(),jt.getTriggerGroup())
                    .withSchedule(cron).build();

            //执行保存
            scheduler.scheduleJob(detail,trigger);
            map.put("is",true);
            map.put("msg",jt.getJobName()+"定时任务构建成功！");


        }catch (Exception e){
            map.put("is",false);
            map.put("msg",jt.getJobName()+"定时任务构建失败！");
            e.printStackTrace();
        }
        return map;
    }


    @Override
    public Map<String, Object> update(JobAndTrigger jt) {

        Map<String, Object> map = new HashMap<>();

        try {

            TriggerKey key = TriggerKey.triggerKey(jt.getTriggerName(),jt.getTriggerGroup());
            //构建corn表达式
            CronScheduleBuilder corn = CronScheduleBuilder.cronSchedule(jt.getCorn());

            //重新构建触发器
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(key);

            trigger = trigger.getTriggerBuilder()
                    .withIdentity(key)
                    .withSchedule(corn)
                    .build();

            //
            scheduler.rescheduleJob(key,trigger);
            map.put("is",true);
            map.put("msg","更新定时任务成功");
        }catch (Exception e){
            map.put("is",false);
            map.put("msg","更新定时任务失败");
            e.printStackTrace();
        }

        return map;
    }

    public BaseJob getClass(String className){
        try{
            Class<?> c = Class.forName(className);
            return (BaseJob) c.newInstance();

        }catch (Exception e){
            e.printStackTrace();
        }

        return null;
    }

    @RequestMapping("/runOne")
    public Map<String,Object> renOne(JobAndTrigger jt){
        Map<String,Object> map = new HashMap<>();
        if ("ACQUIRED".equals(jt.getState())){
            map.put("msg","任务正在执行，无法再执行一次......");
            return map;
        }
        JobDetail job = JobBuilder.newJob(getClass(jt.getClassName()).getClass()).build();
        //创建指定一个时间触发，不重复
        SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
                .withIdentity("oneTrigger","oneTriggerGroup")
                //.startAt(new Date())//立即执行
                .startNow()
                .build();

        try {

            scheduler.scheduleJob(trigger);
            map.put("msg", "任务开始执行且只执行一次");

        }catch (Exception e){
            e.printStackTrace();
        }

        return map;
    }*/

/**
 *
 */
@RestController
@RequestMapping("/system/sc")
public class SchedulerController extends BaseController<JobAndTrigger> {

    @Resource(name="schedulerService")
    private SchedulerService ss;

    @Autowired
    private Scheduler scheduler;

    @Override
    public Map<String, Object> find(JobAndTrigger jt) {
        List<JobAndTrigger> list = ss.find();
        return this.findMap(list,list.size());
    }

    @Override
    public Map<String, Object> add(JobAndTrigger jt) {
        Map<String, Object> map = new HashMap<>();
        try {
            //启动调度器
            scheduler.start();
            //构建任务详情
            JobDetail detail = JobBuilder.newJob(getClass(jt.getClassName()).getClass())
                    .withIdentity(jt.getJobName(),jt.getJobGroup())
                    .build();

            //corn表达式的构建
            CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule(jt.getCorn());

            //构建新的触发器
            CronTrigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(jt.getTriggerName(),jt.getTriggerGroup())
                    .withSchedule(cron).build();

            //执行保存
            scheduler.scheduleJob(detail,trigger);
            map.put("is",true);
            map.put("msg",jt.getJobName()+"定时任务构建成功!");

        }catch (Exception e){
            map.put("is",false);
            map.put("msg",jt.getJobName()+"定时任务构建失败!");
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> update(JobAndTrigger jt) {
        Map<String, Object> map = new HashMap<>();
        try{
            TriggerKey key = TriggerKey.triggerKey(jt.getTriggerName(),jt.getTriggerGroup());
            //构建corn表达式
            CronScheduleBuilder corn = CronScheduleBuilder.cronSchedule(jt.getCorn());

            //重新构建触发器
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(key);
            trigger = trigger.getTriggerBuilder()
                    .withIdentity(key)
                    .withSchedule(corn).build();

            scheduler.rescheduleJob(key,trigger);
            map.put("is",true);
            map.put("msg","更新定时任务成功");
        }catch (Exception e){
            map.put("is",false);
            map.put("msg","更新定时任务失败");
            e.printStackTrace();
        }
        return map;
    }

    public BaseJob getClass(String className){
        try{
            Class<?> c = Class.forName(className);
            return (BaseJob)c.newInstance();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping("/recent5TriggerTime")
    public List<String> recent5TriggerTime(@RequestParam(value = "cron") String cron){
        List<String> list = new ArrayList<>();
        CronTrigger ct;
        try{
            ct = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
            List<Date> dates = TriggerUtils.computeFireTimes((OperableTrigger) ct,null,5);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for(Date d:dates){
                list.add(sdf.format(d));
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return list;
    }

    @RequestMapping("/runOne")
    public Map<String,Object> runOne(JobAndTrigger s){//JobAndTrigger
        Map<String,Object> map = new HashMap<>();
        if("ACQUIRED".equals(s.getState())){
            map.put("msg","任务正在执行，无法再执行一次....");
            return map;
        }

        JobDetail job = JobBuilder.newJob(getClass(s.getClassName()).getClass()).build();

        //指定一个时间触发，不重复
        SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
                .withIdentity("oneTrigger","oneTriggerGroup")
                //.startAt(new Date()) //指定一个时间执行
                .startNow()//立即执行
                .build();
        try {
            scheduler.scheduleJob(job,trigger);
            map.put("msg", "任务开始执行且执行一次");
        }catch (Exception e){
            e.printStackTrace();
        }
        return map;
    }

}
